﻿package {
	
	import flash.display.MovieClip;
	
	import flash.net.*;
	
	import flash.events.*;
	
	import flash.utils.setTimeout;
	import flash.utils.setInterval;
	import flash.utils.clearInterval;
	import flash.utils.ByteArray;
	
	import fl.transitions.Tween;
	import fl.transitions.easing.Strong;
	
	
	public class SudokuPSO  extends MovieClip {
		
		private var sendingStream:String = "";
		private var intId:Number = 0;
		private var runFor:uint = 10;
		private var currentRun:uint = 0;
		private var allTimeFitness:uint = 0;
		private var aTweens:Array = new Array();
		
		public function SudokuPSO() {
			
			trace("Sudoku");
			addToConsole("PSO Sudoku v 1.0 ...");
			addToConsole("Above we have a default configuration for Sudoku.");
			addToConsole("Feel free to edit that configuration for your needs.");
			addToConsole('Press "Find solution" to get the solution for the entered configuration!');
			addToConsole('Hope you enjoy this interface!');
			
			//InitialSudoku.displayRawData();
			InitialSudoku.editable = true;
			
			sendingStream = "";
			
			
            sendingStream += "X 8 X X 4 X X 3 X\r\n";
            sendingStream += "3 X X 6 X X X X X\r\n";
            sendingStream += "X 5 6 2 X X X X 7\r\n";
            sendingStream += "X 9 7 3 X X X X X\r\n";
            sendingStream += "8 X X X X X X X 1\r\n";
            sendingStream += "X X X X X 5 2 9 X\r\n";
            sendingStream += "4 X X X X 1 3 2 X\r\n";
            sendingStream += "X X X X X 4 X X 5\r\n";
            sendingStream += "X 1 X X 8 X X 4 X";
			
			InitialSudoku.display(sendingStream);
			
			//var mySocket:Socket = new Socket();
			
			FindSolution.addEventListener(MouseEvent.CLICK, onClick);

		}
		
		public function addToConsole(val:String):void {
			SudokuConsole.appendText(val + "\n\n");
		}
		
		private function onClick(evt:MouseEvent):void {
			
			FindSolution.enabled = false;
			// increase currentCount
			currentRun++;
			
			
			var myURLLoader:URLLoader = new URLLoader();
			var myURLVariables:URLVariables = new URLVariables();
			var myURLRequest:URLRequest = new URLRequest();
			myURLRequest.method = URLRequestMethod.POST;
			
			//myURLLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
			myURLLoader.dataFormat = URLLoaderDataFormat.TEXT;
			
			//myURLRequest.url = "http://localhost:8080/SudokuPSO";
			
			// local
			//myURLRequest.url = "http://localhost:8084/SudokuServletAPI/Pso";
			
			// remote
			myURLRequest.url = "http://94.52.53.120:8888/SudokuServletAPI/Pso";
			
			myURLVariables.sentData = escape(sendingStream);
			//myURLLoader.data = myURLVariables;
			var myBA:ByteArray = new ByteArray();
			myBA.writeUTF(sendingStream);
			//trace(myBA.toString());
			myURLRequest.data = myBA;
			
			myURLLoader.addEventListener(Event.COMPLETE, onLoadCompleted);
			myURLLoader.load(myURLRequest);
			
			//intId = setInterval(intervaled, 1500);
			//setTimeout(timedOut, 9000);
			//SudokuConsole.text = "";
			
		}
		
		private function onLoadCompleted(evt:Event):void {
			var myBA:ByteArray = new ByteArray();
			
			var resp:String = evt.currentTarget.data as String;
			
			var aResp:Array = resp.split("\r\n");
			
			
			var currFitness:uint = uint(aResp[0]);
			displayFitness(currFitness);
			allTimeFitness += currFitness;
			
			addToConsole("At run no." + currentRun + " server found a fitness of: " + currFitness);
			
			aResp.shift();
			var aDisplay:Array = aResp;
			var sDisplay:String = aDisplay.join("\r\n");
			FinalSudoku.display(sDisplay);
			var target:MovieClip = this["analyzerBar" + (currentRun-1)];
			target['solution'] = sDisplay;
			target.useHandCursor = true;
			target.buttonMode = true;
			target.addEventListener(MouseEvent.CLICK, displaySolution);
			
			if(currentRun < runFor) {
				onClick(null);
			} else {
				addToConsole("The average of the fitness for 10 runs  was: " + (allTimeFitness / 10));
				FindSolution.enabled = true;
			}
		}
		
		private function displayFitness(val:uint):void {
			var target:MovieClip = this["analyzerBar" + (currentRun-1)];
			aTweens.push(new Tween(target, "height", Strong.easeOut, target.height, target.height + (((val - 220)/(243 - 220)) * 150), 2, true));
		}
		
		private function displaySolution(evt:MouseEvent):void {
			var target:MovieClip = MovieClip(evt.currentTarget);
			FinalSudoku.display(target['solution']);
		}
		
		private function intervaled():void {
			var tmp:uint = 0;
			tmp =  Math.floor(Math.random() * 4) + 240;
			//var tmp:uint = 243;
			addToConsole("best fitness " + tmp);
		}
		
		private function timedOut():void {
			
			clearInterval(intId);
			
			var solution:String = "";
			
            solution += "7 8 2 1 4 9 5 3 6\r\n";
            solution += "3 4 1 6 5 7 9 8 2\r\n";
            solution += "9 5 6 2 3 8 4 1 7\r\n";
            solution += "5 9 7 3 1 2 8 6 4\r\n";
            solution += "8 2 3 4 9 6 7 5 1\r\n";
            solution += "1 6 4 8 7 5 2 9 3\r\n";
            solution += "4 7 9 5 6 1 3 2 8\r\n";
            solution += "6 3 8 9 2 4 1 7 5\r\n";
            solution += "2 1 5 7 8 3 6 4 9";
			
			FinalSudoku.display(solution);
			
		}
		
	}
	
}